// Copyright(C) 2002-2003 Hugo Rumayor Montemayor, All rights reserved.
using System;
using System.Collections;

namespace ID3Lib
{
	/// <summary>
	/// Builder factory that creates frames
	/// </summary>
	///<remarks>
	/// The FrameFactory class creates the correct frame based on the four bytes each frame uses
	/// to describe its type, also a description of the frame is added.
	///</remarks>
	public class FrameFactory
	{
		#region Fields
		/// <summary>
		/// Singleton frame factory
		/// </summary>
		private static FrameFactory _instance = new FrameFactory();
		
		/// <summary>
		/// Keep a relation between frame Frames and descriptions of them
		/// </summary>
		private Hashtable _hash = new Hashtable();
		#endregion

		#region Constructors
		/// <summary>
		/// Create a FrameFactory.
		/// </summary>
		private FrameFactory()
		{
			Intitalize();
		}
		#endregion

		#region Methods
		/// <summary>
		/// Obtain a human description of a tag
		/// </summary>
		/// <param name="tag">the four character frame name</param>
		/// <returns>description of the tag</returns>
		private string Description(string tag)
		{
			if(_instance._hash.ContainsKey(tag))
			{
				return (string)_instance._hash[tag];
			}
			else
			{
				if(tag[0] == 'T')
				{
					return "User defined text information frame";
				}
				if(tag[0] == 'W')
				{
					return "User defined URL link frame";
				}
				return "Unknown tag";
			}
		}

		/// <summary>
		/// Builds a frame base, based on the frame tag type.
		/// </summary>
		/// <param name="tag">The ID3v2 tag type</param>
		/// <returns>Frame required for the frame type</returns>
		public static FrameBase Build(string tag)
		{
			FrameBase baseFrame;
			switch(tag)
			{
				case "USLT":
				case "COMM":
				{
					baseFrame = new FrameLCText(tag);
					break;
				}
				case "APIC":
				{
					baseFrame = new FrameAPIC(tag);
					break;
				}
				case "GEOB":
				{
					baseFrame = new FrameGEOB(tag);
					break;
				}
				default:
				{
					if(tag[0] == 'T') //(TXXX) Default Text tag
					{
						baseFrame = new FrameText(tag);	//default
						break;
					}
					if(tag[0] == 'W') //(WXXX) Default Web tag
					{
						baseFrame = new FrameURL(tag); //default
						break;
					}
					// Unknown tag, used as a container for unknown frames
					baseFrame = new FrameUnknown(tag);
					break;
				}
			}
			baseFrame.SetDescription(_instance.Description(tag));
			return baseFrame;
		}

		/// <summary>
		/// Fill the hash with the frame descriptors
		/// </summary>
		private void Intitalize()
		{
			// ID3v2.3
			_hash.Add("TYER","Recording Year");
			// ID3v2.4
			_hash.Add("AENC","Audio encryption");
			_hash.Add("APIC","Attached picture");
			_hash.Add("ASPI","Audio seek point index");

			_hash.Add("COMM","Comments");
			_hash.Add("COMR","Commercial frame");

			_hash.Add("ENCR","Encryption method registration");
			_hash.Add("EQU2","Equalisation");
			_hash.Add("ETCO","Event timing codes");

			_hash.Add("GEOB","General encapsulated object");
			_hash.Add("GRID","Group identification registration");

			_hash.Add("LINK","Linked information");

			_hash.Add("MCDI","Music CD identifier");
			_hash.Add("MLLT","MPEG location lookup table");

			_hash.Add("OWNE","Ownership frame");

			_hash.Add("PRIV","Private frame");
			_hash.Add("PCNT","Play counter");
			_hash.Add("POPM","Popularimeter");
			_hash.Add("POSS","Position synchronisation frame");

			_hash.Add("RBUF","Recommended buffer size");
			_hash.Add("RVA2","Relative volume adjustment");
			_hash.Add("RVRB","Reverb");

			_hash.Add("SEEK","Seek frame");
			_hash.Add("SIGN","Signature frame");
			_hash.Add("SYLT","Synchronised lyric/text");
			_hash.Add("SYTC","Synchronised tempo codes");

			_hash.Add("TALB","Album/Movie/Show title");
			_hash.Add("TBPM","Beats per minute)");
			_hash.Add("TCOM","Composer");
			_hash.Add("TCON","Content type");
			_hash.Add("TCOP","Copyright message");
			_hash.Add("TDEN","Encoding time");
			_hash.Add("TDLY","Playlist delay");
			_hash.Add("TDOR","Original release time");
			_hash.Add("TDRC","Recording time");
			_hash.Add("TDRL","Release time");
			_hash.Add("TDTG","Tagging time");
			_hash.Add("TENC","Encoded by");
			_hash.Add("TEXT","Lyricist/Text writer");
			_hash.Add("TFLT","File type");
			_hash.Add("TIPL","Involved people list");
			_hash.Add("TIT1","Content group description");
			_hash.Add("TIT2","Title/songname/content description");
			_hash.Add("TIT3","Subtitle/Description refinement");
			_hash.Add("TKEY","Initial key");
			_hash.Add("TLAN","Language(s)");
			_hash.Add("TLEN","Length");
			_hash.Add("TMCL","Musician credits list");
			_hash.Add("TMED","Media type");
			_hash.Add("TMOO","Mood");
			_hash.Add("TOAL","Original album/movie/show title");
			_hash.Add("TOFN","Original filename");
			_hash.Add("TOLY","Original lyricist(s)/text writer(s)");
			_hash.Add("TOPE","Original artist(s)/performer(s)");
			_hash.Add("TOWN","File owner/licensee");
			_hash.Add("TPE1","Lead performer(s)/Soloist(s)");
			_hash.Add("TPE2","Band/orchestra/accompaniment");
			_hash.Add("TPE3","Conductor/performer refinement");
			_hash.Add("TPE4","Interpreted, remixed, or otherwise modified by");
			_hash.Add("TPOS","Part of a set");
			_hash.Add("TPRO","Produced notice");
			_hash.Add("TPUB","Publisher");
			_hash.Add("TRCK","Track number/Position in set");
			_hash.Add("TRSN","Internet radio station name");
			_hash.Add("TRSO","Internet radio station owner");
			_hash.Add("TSOA","Album sort order");
			_hash.Add("TSOP","Performer sort order");
			_hash.Add("TSOT","Title sort order");
			_hash.Add("TSRC","ISRC (international standard recording code)");
			_hash.Add("TSSE","Software/Hardware and settings used for encoding");
			_hash.Add("TSST","Set subtitle");

			_hash.Add("UFID","Unique file identifier");
			_hash.Add("USER","Terms of use");
			_hash.Add("USLT","Unsynchronised lyric/text transcription");

			_hash.Add("WCOM","Commercial information");
			_hash.Add("WCOP","Copyright/Legal information");
			_hash.Add("WOAF","Official audio file webpage");
			_hash.Add("WOAR","Official artist/performer webpage");
			_hash.Add("WOAS","Official audio source webpage");
			_hash.Add("WORS","Official Internet radio station homepage");
			_hash.Add("WPAY","Payment");
			_hash.Add("WPUB","Publishers official webpage");
		}
		#endregion
	}
}
